class Util {
	private constructor() {
	}
	private static instance: Util;
	public static getInstance() {
		if (this.instance == null) {
			this.instance = new Util();
		}
		return this.instance;
	}
	private c = serverConfig.config;

	public findIndex(arr, id) {
		var len = arr.length;
		while (len--) {
			if (arr[len].id === id) {
				return len;
			}
		}
		return -1;
	}
	private NextPointdir = new egret.Point(0, 0);
	private NextPointpos = new egret.Point(0, 0);
	public calculateNextPointEx(curX: number, curY: number, dirX: number, dirY: number, speed: number, output: boolean) {


		this.NextPointdir.setTo(dirX, dirY);
		this.NextPointpos.setTo(curX, curX);


		this.NextPointdir.normalize(speed);

		//     if(output)
		//   console.log( "原来的位置" + curX +"|"+curY + "移动方向" + dirX +"|"+dirY + "新位置" +pos.x +"|" + pos.y );
		return { x: this.NextPointdir.x + this.NextPointpos.x, y: this.NextPointdir.y + this.NextPointpos.y };
	}

	//返回一个随机的方向
	private dirTmp = new egret.Point(0, 0);
	public getRandomDir() {

		var angle = Math.random() * 360 * Math.PI / 180;
		this.dirTmp.setTo(Math.sin(angle), Math.cos(angle));
		this.dirTmp.normalize(1);
		return { x: this.dirTmp.x, y: this.dirTmp.y };
	}

	public getDistance(startPoint, endPoint) {
		//非空
		if (startPoint == null || endPoint == null) {
			console.log("util中getDistance()传输数据为空");
			return null
		}
		var x = Math.abs(endPoint.x - startPoint.x);
		var y = Math.abs(endPoint.y - startPoint.y);
		return Math.sqrt(x * x + y * y);
	}

	public getPointToLineDistance(p1, p2, p) {
		var ans = 0;
		var a = this.getPointDistance(p1, p2);
		var b = this.getPointDistance(p1, p);
		var c = this.getPointDistance(p2, p);
		if (c + b == a) {//点在线段上
			ans = 0;
			return ans;
		}
		if (a <= 0.00001) {//不是线段，是一个点
			ans = b;
			return ans;
		}
		if (c * c >= a * a + b * b) { //组成直角三角形或钝角三角形，p1为直角或钝角
			ans = b;
			return ans;
		}
		if (b * b >= a * a + c * c) {// 组成直角三角形或钝角三角形，p2为直角或钝角
			ans = c;
			return ans;
		}
		// 组成锐角三角形，则求三角形的高
		var p0 = (a + b + c) / 2;// 半周长
		var s = Math.sqrt(p0 * (p0 - a) * (p0 - b) * (p0 - c));// 海伦公式求面积
		ans = 2 * s / a;// 返回点到线的距离（利用三角形面积公式求高）
		return ans;
	}
	public getPointDistance(p, p1) {
		var dis_x = Math.abs(p.x - p1.x);
		var dis_y = Math.abs(p.y - p1.y);
		return Math.sqrt(Math.pow(dis_x, 2) + Math.pow(dis_y, 2));
	}
	public uniformPosition(points, radius) {
		var bestCandidate, maxDistance = 0;
		var numberOfCandidates = 10;

		if (points.length === 0) {
			return this.randomPosition(radius);
		}

		// Generate the candidates
		for (var ci = 0; ci < numberOfCandidates; ci++) {
			var minDistance = Infinity;
			var candidate = this.randomPosition(radius);
			candidate.radius = radius;

			for (var pi = 0; pi < points.length; pi++) {
				var distance = this.getDistance(candidate, points[pi]);
				if (distance < minDistance) {
					minDistance = distance;
				}
			}

			if (minDistance > maxDistance) {
				bestCandidate = candidate;
				maxDistance = minDistance;
			} else {
				return this.randomPosition(radius);
			}
		}

		return bestCandidate;
	}

	public removeItemInPool(list, id) {
		list.splice(this.findIndexEx(list, id), 1);
	}

	public testPP() {
		return;
		var count = egret.$hashCount;
		setInterval(() => {
			var newCount = egret.$hashCount;
			var diff = newCount - count;
			count = newCount;

			console.log(diff)
		}, 1000

		);
	}
	public randomPosition(radius) {
		return {
			radius: 0,//手动添加
			x: this.randomInRange(radius, this.c.gameWidth - radius),
			y: this.randomInRange(radius, this.c.gameHeight - radius)
		};
	}
	public randomInRange(from, to) {
		return Math.floor(Math.random() * (to - from)) + from;
	}
	public log() {
		var log = Math.log;
		return function (n, base) {
			return log(n) / (base ? log(base) : 1);
		};
	}
	public findIndexEx(arr, userId) {
		var len = arr.length;

		while (len--) {
			if (arr[len].id === userId) {
				return len;
			}
		}

		return -1;
	}

	/**两点获取角度 */
	public getRotation(nowpos: any, topos: any) {
		if (nowpos == null) {
			return;
		}
		var px = nowpos.x;
		var py = nowpos.y
		if (topos == null) {
			return;
		}
		var mx = topos.x;
		var my = topos.y;

		var x = Math.abs(px - mx);
		var y = Math.abs(py - my);
		var z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
		var cos = y / z;
		var radina = Math.acos(cos);//用反三角函数求弧度
		var angle = 180 / (Math.PI / radina);//将弧度转换成角度
		if (mx > px && my > py) {//鼠标在第四象限
			angle = 180 - angle;
		}
		if (mx == px && my > py) {//鼠标在y轴负方向上
			angle = 180;
		}
		if (mx > px && my == py) {//鼠标在x轴正方向上
			angle = 90;
		}
		if (mx < px && my > py) {//鼠标在第三象限
			angle = 180 + angle;
		}
		if (mx < px && my == py) {//鼠标在x轴负方向
			angle = 270;
		}
		if (mx < px && my < py) {//鼠标在第二象限
			angle = 360 - angle;
		}
		return isNaN(angle) ? 0 : angle;
	}

	public getCenterPos(startPos, endPos) {
		return { x: (startPos.x + endPos.x) / 2, y: (startPos.y + endPos.y) / 2 };
	}

	/** 
* 判断是否null data == "" ||
* @param data 
*/
	public isNull(data) {
		return (data == undefined || data == null) ? true : false;
	}
	/**四点两线的交点 */
	public segmentsIntr(a, b, c, d) {

		/** 1 解线性方程组, 求线段交点. **/
		// 如果分母为0 则平行或共线, 不相交 
		var denominator = (b.y - a.y) * (d.x - c.x) - (a.x - b.x) * (c.y - d.y);
		if (denominator == 0) {
			return false;
		}

		// 线段所在直线的交点坐标 (x , y) 
		var x = ((b.x - a.x) * (d.x - c.x) * (c.y - a.y)
			+ (b.y - a.y) * (d.x - c.x) * a.x
			- (d.y - c.y) * (b.x - a.x) * c.x) / denominator;
		var y = -((b.y - a.y) * (d.y - c.y) * (c.x - a.x)
			+ (b.x - a.x) * (d.y - c.y) * a.y
			- (d.x - c.x) * (b.y - a.y) * c.y) / denominator;

		/** 2 判断交点是否在两条线段上 **/
		if (
			// 交点在线段1上 
			(x - a.x) * (x - b.x) <= 0 && (y - a.y) * (y - b.y) <= 0
			// 且交点也在线段2上 
			&& (x - c.x) * (x - d.x) <= 0 && (y - c.y) * (y - d.y) <= 0
		) {

			// 返回交点p 
			return {
				x: x,
				y: y
			}
		}
		//否则不相交 
		return false

	}
	//计算角度 起点到终点
	public calculateRotation(player_position: any, mouse_position: any): number {
		var rotation: number = 0;
		var offestx: number = Math.abs(mouse_position.x - player_position.x);
		var offesty: number = Math.abs(mouse_position.y - player_position.y);
		var alpha: number = Math.atan(offestx / offesty);
		rotation = alpha * 180 / Math.PI;
		if (mouse_position.x - player_position.x > 0 && mouse_position.y - player_position.y > 0) {
			rotation = 180 - rotation;
		} else if (mouse_position.x - player_position.x > 0 && mouse_position.y - player_position.y < 0) {
			rotation = rotation;
		} else if (mouse_position.x - player_position.x < 0 && mouse_position.y - player_position.y < 0) {
			rotation = 360 - rotation;
		} else if (mouse_position.x - player_position.x < 0 && mouse_position.y - player_position.y > 0) {
			rotation = 180 + rotation;
		}
		//console.log(rotation);
		return rotation;
	}
}